package mi.payment.utils.secure;

import java.security.Key;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;

/**
 * @author Administrator on 2016/8/16.
 */
public class TriDes {

    /**
     * 3des 双倍长
     * ECB加密,不要IV
     *
     * @param key  密钥 16字节
     * @param data 明文
     * @return Base64编码的密文
     * @throws Exception 异常
     */
    public static byte[] Des3EncodeECB2(byte[] key, byte[] data) throws Exception {
        byte[] tmpKey = new byte[24];
        System.arraycopy(key, 0, tmpKey, 0, 16);
        System.arraycopy(key, 0, tmpKey, 16, 8);
        return Des3EncodeECB(tmpKey, data);
    }

    /**
     * ECB加密,不要IV
     *
     * @param key  密钥
     * @param data 明文
     * @return Base64编码的密文
     * @throws Exception 异常
     */
    private static byte[] Des3EncodeECB(byte[] key, byte[] data) throws Exception {
        DESedeKeySpec spec = new DESedeKeySpec(key);
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
        Key desKey = keyFactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE, desKey);
        byte[] bytes = cipher.doFinal(data);
        return bytes;
    }

    /**
     * 3des 双倍长
     * ECB解密,不要IV
     *
     * @param key  密钥
     * @param data Base64编码的密文
     * @return 明文
     * @throws Exception 异常
     */
    public static byte[] Des3DecodeECB2(byte[] key, byte[] data) throws Exception {
        byte[] tmpKey = new byte[24];
        System.arraycopy(key, 0, tmpKey, 0, 16);
        System.arraycopy(key, 0, tmpKey, 16, 8);
        return Des3DecodeECB(tmpKey, data);
    }

    /**
     * ECB解密,不要IV
     *
     * @param key  密钥
     * @param data Base64编码的密文
     * @return 明文
     * @throws Exception 异常
     */
    private static byte[] Des3DecodeECB(byte[] key, byte[] data) throws Exception {
        DESedeKeySpec spec = new DESedeKeySpec(key);
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
        Key desKey = keyFactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding");
        cipher.init(Cipher.DECRYPT_MODE, desKey);
        byte[] bytes = cipher.doFinal(data);
        return bytes;
    }

    /**
     * ECB加密,不要IV
     *
     * @param key  密钥
     * @param data 明文
     * @return Base64编码的密文
     * @throws Exception 异常
     */
    public static byte[] DesEncodeECB(byte[] key, byte[] data) throws Exception {
        DESKeySpec spec = new DESKeySpec(key);
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        Key desKey = keyFactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE, desKey);
        byte[] bytes = cipher.doFinal(data);
        return bytes;
    }

    /**
     * ECB解密,不要IV
     *
     * @param key  密钥
     * @param data Base64编码的密文
     * @return 明文
     * @throws Exception 异常
     */
    public static byte[] DesDecodeECB(byte[] key, byte[] data) throws Exception {
        DESKeySpec spec = new DESKeySpec(key);
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        Key desKey = keyFactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
        cipher.init(Cipher.DECRYPT_MODE, desKey);
        byte[] bytes = cipher.doFinal(data);
        return bytes;
    }

    /**
     * CBC加密
     *
     * @param key   密钥
     * @param keyIv IV
     * @param data  明文
     * @return Base64编码的密文
     * @throws Exception 异常
     */
    public static byte[] Des3EncodeCBC(byte[] key, byte[] keyIv, byte[] data) throws Exception {
        DESedeKeySpec spec = new DESedeKeySpec(key);
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
        Key desKey = keyFactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance("DESede/CBC/NoPadding");
        IvParameterSpec ips = new IvParameterSpec(keyIv);
        cipher.init(Cipher.ENCRYPT_MODE, desKey, ips);
        byte[] bytes = cipher.doFinal(data);
        return bytes;
    }

    /**
     * CBC解密
     *
     * @param key   密钥
     * @param keyIv IV
     * @param data  Base64编码的密文
     * @return 明文
     * @throws Exception 异常
     */
    public static byte[] Des3DecodeCBC(byte[] key, byte[] keyIv, byte[] data) throws Exception {
        DESedeKeySpec spec = new DESedeKeySpec(key);
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
        Key desKey = keyFactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance("DESede/CBC/NoPadding");
        IvParameterSpec ips = new IvParameterSpec(keyIv);
        cipher.init(Cipher.DECRYPT_MODE, desKey, ips);
        byte[] bytes = cipher.doFinal(data);
        return bytes;
    }


}
